﻿// This is an open source non-commercial project. Dear PVS-Studio, please check it.
// PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com

// ReSharper disable CheckNamespace
// ReSharper disable CommentTypo
// ReSharper disable IdentifierTypo

/* TextSytle.cs --
 * Ars Magna project, http://arsmagna.ru
 */

#region Using directives

using System.Drawing;
using System;

#endregion

#nullable enable

namespace Fctb;

/// <summary>
/// Style for chars rendering
/// This renderer can draws chars, with defined fore and back colors
/// </summary>
public class TextStyle
    : Style
{
    /// <summary>
    /// Кисть для текста.
    /// </summary>
    public Brush? ForeBrush { get; set; }

    /// <summary>
    /// Кисть для фона.
    /// </summary>
    public Brush? BackgroundBrush { get; set; }

    /// <summary>
    /// Стиль шрифта.
    /// </summary>
    public FontStyle FontStyle { get; set; }

    //public readonly Font Font;
    public StringFormat stringFormat;

    /// <summary>
    /// Конструктор.
    /// </summary>
    public TextStyle
        (
            Brush? foreBrush,
            Brush? backgroundBrush,
            FontStyle fontStyle
        )
    {
        ForeBrush = foreBrush;
        BackgroundBrush = backgroundBrush;
        FontStyle = fontStyle;
        stringFormat = new StringFormat (StringFormatFlags.MeasureTrailingSpaces);
    }

    /// <inheritdoc cref="Style.Draw"/>
    public override void Draw
        (
            Graphics graphics,
            Point position,
            TextRange range
        )
    {
        //draw background
        if (BackgroundBrush != null)
        {
            graphics.FillRectangle (BackgroundBrush, position.X, position.Y,
                (range.End.Column - range.Start.Column) * range._textBox.CharWidth, range._textBox.CharHeight);
        }

        //draw chars
        using (var f = new Font (range._textBox.Font, FontStyle))
        {
            var line = range._textBox[range.Start.Line];
            float dx = range._textBox.CharWidth;
            float y = position.Y + range._textBox.LineInterval / 2;
            float x = position.X - range._textBox.CharWidth / 3;

            if (ForeBrush == null)
            {
                ForeBrush = new SolidBrush (range._textBox.ForeColor);
            }

            if (range._textBox.ImeAllowed)
            {
                //IME mode
                for (var i = range.Start.Column; i < range.End.Column; i++)
                {
                    var size = SyntaxTextBox.GetCharSize (f, line[i].c);

                    var gs = graphics.Save();
                    var k = size.Width > range._textBox.CharWidth + 1 ? range._textBox.CharWidth / size.Width : 1;
                    graphics.TranslateTransform (x, y + (1 - k) * range._textBox.CharHeight / 2);
                    graphics.ScaleTransform (k, (float)Math.Sqrt (k));
                    graphics.DrawString (line[i].c.ToString(), f, ForeBrush, 0, 0, stringFormat);
                    graphics.Restore (gs);
                    x += dx;
                }
            }
            else
            {
                //classic mode
                for (var i = range.Start.Column; i < range.End.Column; i++)
                {
                    //draw char
                    graphics.DrawString (line[i].c.ToString(), f, ForeBrush, x, y, stringFormat);
                    x += dx;
                }
            }
        }
    }

    /// <inheritdoc cref="Style.GetCSS"/>
    public override string GetCSS()
    {
        var result = "";

        if (BackgroundBrush is SolidBrush)
        {
            var s = ExportToHtml.GetColorAsString ((BackgroundBrush as SolidBrush).Color);
            if (s != "")
            {
                result += "background-color:" + s + ";";
            }
        }

        if (ForeBrush is SolidBrush)
        {
            var s = ExportToHtml.GetColorAsString ((ForeBrush as SolidBrush).Color);
            if (s != "")
            {
                result += "color:" + s + ";";
            }
        }

        if ((FontStyle & FontStyle.Bold) != 0)
        {
            result += "font-weight:bold;";
        }

        if ((FontStyle & FontStyle.Italic) != 0)
        {
            result += "font-style:oblique;";
        }

        if ((FontStyle & FontStyle.Strikeout) != 0)
        {
            result += "text-decoration:line-through;";
        }

        if ((FontStyle & FontStyle.Underline) != 0)
        {
            result += "text-decoration:underline;";
        }

        return result;
    }

    /// <inheritdoc cref="GetRTF"/>
    public override RtfStyleDescriptor GetRTF()
    {
        var result = new RtfStyleDescriptor();

        if (BackgroundBrush is SolidBrush)
        {
            result.BackColor = (BackgroundBrush as SolidBrush)!.Color;
        }

        if (ForeBrush is SolidBrush)
        {
            result.ForeColor = (ForeBrush as SolidBrush)!.Color;
        }

        if ((FontStyle & FontStyle.Bold) != 0)
        {
            result.AdditionalTags += @"\b";
        }

        if ((FontStyle & FontStyle.Italic) != 0)
        {
            result.AdditionalTags += @"\i";
        }

        if ((FontStyle & FontStyle.Strikeout) != 0)
        {
            result.AdditionalTags += @"\strike";
        }

        if ((FontStyle & FontStyle.Underline) != 0)
        {
            result.AdditionalTags += @"\ul";
        }

        return result;
    }
}
